//
//  NetworkManager.swift
//  NetworkDemo
//
//  Created by xiaoyouxinqing on 4/30/20.
//  Copyright © 2020 xiaoyouxinqing. All rights reserved.
//

import Foundation
import Alamofire
import SwiftyJSON
//为什么需要NetworkManager？


typealias NetworkRequestResult = Result<Data, Error>
typealias NetworkRequestCompletion = (NetworkRequestResult) -> Void

let NetworkAPIBaseURL = "https://mock.apifox.cn/m1/2039064-0-default"


//NetworkManager用来发出http请求，并且设置请求参数
//它返回请求结果的二进制数据流，即Data数据
class NetworkManager {
    //单例模式
    static let shared = NetworkManager()
    
    //实际开发中GET和POST方法的headers通常是相同的
    var commonHeaders: HTTPHeaders = ["userId": "1000000001", "token": "sdfkasdjfkjklasjdfj"]
    
    private init() {}
    
    
    //AF.request.responseData返回AFDataResponse<Data>
    //response.result为Result<Data, AFError>类型
    //默认情况下Alamofire请求完成的闭包在主线程中执行，不存在线程安全问题。网络请求在子线程中执行
    //parameters是GET方法拼接在路径后面的参数
    //@discardableResult表示忽略返回值
    //@escaping
    @discardableResult
    func requestGet(path: String, parameters: Parameters?, completion: @escaping NetworkRequestCompletion) -> DataRequest {
        AF.request(NetworkAPIBaseURL + path,
                   //不写method,默认为GET
                   parameters: parameters,      //parameters和headers的区别？
                   headers: commonHeaders,
                   requestModifier: { $0.timeoutInterval = 15 })    //请求超时时间
            .responseData { response in         //返回值为Self,即返回这个函数的返回值DataRequest
                switch response.result {
                case let .success(data):        //.success(data)将枚举类型的参数取出来，先不管语言特性
                    completion(.success(data))
                case let .failure(error):
                    completion(self.handleError(error))
                }
        }
    }
    
    ////POST方法parameters是写在body里面
    @discardableResult
    func requestPost(path: String, parameters: Parameters?, completion: @escaping NetworkRequestCompletion) -> DataRequest {
        AF.request(NetworkAPIBaseURL + path,
                   method: .post,
                   parameters: parameters,
                   encoding: JSONEncoding.prettyPrinted,    //将body中的参数转化成JSON
                   headers: commonHeaders,
                   requestModifier: { $0.timeoutInterval = 15 })
            .responseData { response in
                switch response.result {
                case let .success(data): completion(.success(data))
                case let .failure(error): completion(self.handleError(error))
                }
        }
    }

    
    //
    
    private func handleError(_ error: AFError) -> NetworkRequestResult {
        if let underlyingError = error.underlyingError {
            let nserror = underlyingError as NSError
            let code = nserror.code
            if  code == NSURLErrorNotConnectedToInternet ||
                code == NSURLErrorTimedOut ||
                code == NSURLErrorInternationalRoamingOff ||
                code == NSURLErrorDataNotAllowed ||
                code == NSURLErrorCannotFindHost ||
                code == NSURLErrorCannotConnectToHost ||
                code == NSURLErrorNetworkConnectionLost {
                var userInfo = nserror.userInfo
                userInfo[NSLocalizedDescriptionKey] = "网络连接有问题喔～"
                let currentError = NSError(domain: nserror.domain, code: code, userInfo: userInfo)
                return .failure(currentError)
            }
        }
        return .failure(error)
    }
}
